{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f33315fe",
   "metadata": {
    "origin_pos": 0
   },
   "source": [
    "# 延后初始化\n",
    ":label:`sec_deferred_init`\n",
    "\n",
    "到目前为止，我们忽略了建立网络时需要做的以下这些事情：\n",
    "\n",
    "* 我们定义了网络架构，但没有指定输入维度。\n",
    "* 我们添加层时没有指定前一层的输出维度。\n",
    "* 我们在初始化参数时，甚至没有足够的信息来确定模型应该包含多少参数。\n",
    "\n",
    "有些读者可能会对我们的代码能运行感到惊讶。\n",
    "毕竟，深度学习框架无法判断网络的输入维度是什么。\n",
    "这里的诀窍是框架的*延后初始化*（defers initialization），\n",
    "即直到数据第一次通过模型传递时，框架才会动态地推断出每个层的大小。\n",
    "\n",
    "在以后，当使用卷积神经网络时，\n",
    "由于输入维度（即图像的分辨率）将影响每个后续层的维数，\n",
    "有了该技术将更加方便。\n",
    "现在我们在编写代码时无须知道维度是什么就可以设置参数，\n",
    "这种能力可以大大简化定义和修改模型的任务。\n",
    "接下来，我们将更深入地研究初始化机制。\n",
    "\n",
    "## 实例化网络\n",
    "\n",
    "首先，让我们实例化一个多层感知机。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf346ce2",
   "metadata": {
    "origin_pos": 3
   },
   "source": [
    "此时，因为输入维数是未知的，所以网络不可能知道输入层权重的维数。\n",
    "因此，框架尚未初始化任何参数，我们通过尝试访问以下参数进行确认。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28870c12",
   "metadata": {
    "origin_pos": 10
   },
   "source": [
    "接下来让我们将数据通过网络，最终使框架初始化参数。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d677279",
   "metadata": {
    "origin_pos": 13
   },
   "source": [
    "一旦我们知道输入维数是20，框架可以通过代入值20来识别第一层权重矩阵的形状。\n",
    "识别出第一层的形状后，框架处理第二层，依此类推，直到所有形状都已知为止。\n",
    "注意，在这种情况下，只有第一层需要延迟初始化，但是框架仍是按顺序初始化的。\n",
    "等到知道了所有的参数形状，框架就可以初始化参数。\n",
    "\n",
    "## 小结\n",
    "\n",
    "* 延后初始化使框架能够自动推断参数形状，使修改模型架构变得容易，避免了一些常见的错误。\n",
    "* 我们可以通过模型传递数据，使框架最终初始化参数。\n",
    "\n",
    "## 练习\n",
    "\n",
    "1. 如果指定了第一层的输入尺寸，但没有指定后续层的尺寸，会发生什么？是否立即进行初始化？\n",
    "1. 如果指定了不匹配的维度会发生什么？\n",
    "1. 如果输入具有不同的维度，需要做什么？提示：查看参数绑定的相关内容。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f81a060",
   "metadata": {
    "origin_pos": 15,
    "tab": [
     "pytorch"
    ]
   },
   "source": [
    "[Discussions](https://discuss.d2l.ai/t/5770)\n"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}